﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text;
using psafth.AMB;
using System.Drawing;

namespace psafth.FSR.Lapcounter.UserControls
{
    public partial class ReportControl
    {
        public List<RaceCompetitor> Racers { get; set; }

        public ReportControl(List<RaceCompetitor> Competitors, string Header)
        {
            if (Competitors.Count < 1)
                return;

            string FilePath = Header + DateTime.Now.ToString("yyyy-MM-dd HH mm") + ".pdf";

            List<RaceCompetitor> SortedCompetitors = new List<RaceCompetitor>(Competitors);

            SortedCompetitors.Sort(StartnumberComparison);

            if (SortedCompetitors.Sum(l => l.Laps.Count()) > 0)
            {

                SortedCompetitors.Sort((first, second) =>
                {
                    int result = first.Laps.Count(la => la.IsValid).CompareTo(second.Laps.Count(la => la.IsValid));
                    return result != 0 ? result : second.EndTime.CompareTo(first.EndTime);
                });
            }

            //Create Document class object and set its size to letter and give space left, right, Top, Bottom Margin
            Document doc = new Document(iTextSharp.text.PageSize.A4.Rotate(), 20, 20, 22, 35);

            FilePath = FilePath.Replace(':', '-');
            FilePath = FilePath.Replace('/', '-');

            PdfWriter wri = PdfWriter.GetInstance(doc, new FileStream(FilePath, FileMode.Create));
            doc.Open();//Open Document to write


            iTextSharp.text.Font Calibri = FontFactory.GetFont("Calibri", 10, iTextSharp.text.Font.NORMAL);
            iTextSharp.text.Font CalibriBold = FontFactory.GetFont("Calibri", 10, iTextSharp.text.Font.BOLD);
            iTextSharp.text.Font CalibriHeader = FontFactory.GetFont("Calibri", 60, iTextSharp.text.Font.BOLD);
            iTextSharp.text.Font CalibriStrikeThrough = FontFactory.GetFont("Calibri", 10, iTextSharp.text.Font.STRIKETHRU);

            iTextSharp.text.Font cbh = new iTextSharp.text.Font(CalibriHeader);

            cbh.Size = 30;
            cbh.SetStyle(1);

            Chunk h = new Chunk(Header, cbh);

            System.Drawing.Bitmap bitmap = global::psafth.FSR.Lapcounter.Properties.Resources.hmbk;

            ImageConverter ic = new ImageConverter();

            iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance((byte[])ic.ConvertTo(bitmap, typeof(byte[])));

            logo.ScaleAbsolute(100, 100);
            logo.SetAbsolutePosition(710, 470);
            logo.Alignment = iTextSharp.text.Image.TEXTWRAP;

            doc.Add(logo);

            Paragraph paragraph = new Paragraph(h);

            PdfPTable ResultTable = new PdfPTable(4);

            ResultTable.TotalWidth = 400f;
            ResultTable.LockedWidth = true;
            ResultTable.SetWidths(new float[] { 4f, 2f, 1f, 2f });

            ResultTable.HorizontalAlignment = 0;

            //leave a gap before and after the table

            ResultTable.SpacingBefore = 15f;

            ResultTable.SpacingAfter = 15f;

            ResultTable.DefaultCell.Padding = 3;
            ResultTable.DefaultCell.BorderColor = BaseColor.GRAY;

            Chunk f = new Chunk("Namn", new iTextSharp.text.Font(CalibriBold));
            Chunk y = new Chunk("Varv", new iTextSharp.text.Font(CalibriBold));
            Chunk u = new Chunk("B. varv", new iTextSharp.text.Font(CalibriBold));
            Chunk w = new Chunk("Transponder", new iTextSharp.text.Font(CalibriBold));

            ResultTable.AddCell(new Phrase(f));
            ResultTable.AddCell(new Phrase(y));
            ResultTable.AddCell(new Phrase(u));
            ResultTable.AddCell(new Phrase(w));

            PdfPTable TimeTable = new PdfPTable(Competitors.Count);
            //actual width of table in points

            TimeTable.TotalWidth = Competitors.Count * 66f;

            //fix the absolute width of the table

            TimeTable.LockedWidth = true;

            //relative col widths in proportions - 1/3 and 2/3

            float[] widths = new float[Competitors.Count];

            for (int i = 0; i < widths.Length; i++)
            {
                widths[i] = 1f;
            }

            TimeTable.SetWidths(widths);

            TimeTable.HorizontalAlignment = 0;

            //leave a gap before and after the table

            TimeTable.SpacingBefore = 15f;

            TimeTable.SpacingAfter = 15f;

            SortedCompetitors.Reverse();

            double bestofall = 30 * 1000;

            foreach (RaceCompetitor boa in SortedCompetitors)
            {
                if (boa.BestLap > 0)
                {
                    if (boa.BestLap <= bestofall)
                        bestofall = boa.BestLap;
                }
            }

            int Position = 1;
            foreach (RaceCompetitor c in SortedCompetitors)
            {
                iTextSharp.text.Font b = new iTextSharp.text.Font(Calibri);
                if (c.BestLap == bestofall)
                    b = new iTextSharp.text.Font(CalibriBold);

                b.Size = 12;

                Chunk n;

                if (c.StartNumber > 0)
                {
                    n = new Chunk(Position + ". [" + c.StartNumber + "] " + c.FirstName + " " + c.SurName, b);
                }
                else
                {
                    n = new Chunk(Position + ". " + c.FirstName + " " + c.SurName, b);
                }

                Phrase pName = new Phrase(n);

                Chunk l;

                if (c.EndTime < 0)
                {
                    l = new Chunk(string.Format("{0} (DSQ)", c.Laps.Count(la => la.IsValid).ToString()), b);
                }
                else
                {
                    l = new Chunk(string.Format("{0} ({1}s)", c.Laps.Count(la => la.IsValid).ToString(), AMBCalculator.TrimDouble(c.EndTime, 3)), b);
                }
                
                Phrase pLaps = new Phrase(l);


                Chunk t = new Chunk(c.TransponderId.ToString(), b);

                Phrase pTransp = new Phrase(t);

                string BestLap = string.Empty;

                BestLap = c.BestLap.ToString();

                if (c.BestLap == -1.0)
                    BestLap = "-";

                if (c.BestLap == -2.0)
                    BestLap = "ERROR";

                Chunk be = new Chunk(BestLap, b);
                Phrase pBest = new Phrase(be);

                ResultTable.AddCell(pName);
                ResultTable.AddCell(pLaps);
                ResultTable.AddCell(pBest);
                ResultTable.AddCell(pTransp);

                Position++;
            }


            foreach (RaceCompetitor t in Competitors)
            {
                Phrase ps = new Phrase();

                iTextSharp.text.Font b = new iTextSharp.text.Font(Calibri);
                b.SetStyle(1);
                b.Size = 7;

                Chunk g = new Chunk(t.LicenceNumber + Environment.NewLine + t.FirstName.Substring(0, 1) + ". " + t.SurName + Environment.NewLine, b);

                ps.Add(g);

                int c = 0;

                double best = t.BestLap;

                foreach (Lap l in t.Laps)
                {
                    string isManual = string.Empty;

                    if (l.ManualCount)
                        isManual = "*";

                    c++;
                    if (l.LapTime == best)
                    {
                        iTextSharp.text.Font bt = new iTextSharp.text.Font(CalibriBold);
                        bt.SetStyle(1);
                        bt.Size = 9;

                        ps.Add(new Chunk(c.ToString("00") + " | " + l.LapTime + isManual + Environment.NewLine, bt));

                    }
                    else
                    {
                        iTextSharp.text.Font bt;
                        if (l.IsValid)
                        {
                            bt = new iTextSharp.text.Font(Calibri);
                            bt.SetStyle(0);
                            bt.Size = 9;
                            ps.Add(new Chunk(c.ToString("00") + " | " + l.LapTime + isManual + Environment.NewLine, bt));
                        }
                        else
                        {

                            bt = new iTextSharp.text.Font(CalibriStrikeThrough);
                            bt.SetStyle(iTextSharp.text.Font.STRIKETHRU);
                            bt.Size = 9;
                            ps.Add(new Chunk(c.ToString("00") + " | " + l.LapTime + isManual + Environment.NewLine, bt));
                            c--;
                        }
                    }
                }

                PdfPCell pc = new PdfPCell(ps);

                pc.Border = 0;

                TimeTable.AddCell(pc);
            }

            doc.Add(paragraph);

            doc.Add(ResultTable);

            doc.Add(TimeTable);

            doc.Close(); //Close document

            System.Diagnostics.Process.Start(FilePath);
        }

        public static Comparison<RaceCompetitor> StartnumberComparison = delegate(RaceCompetitor p1, RaceCompetitor p2)
        {
            return p2.StartNumber.CompareTo(p1.StartNumber);
        };

        public static Comparison<RaceCompetitor> CompetitorComparison =
        delegate(RaceCompetitor p1, RaceCompetitor p2)
        {
            return p1.Laps.Count.CompareTo(p2.Laps.Count);
        };

        static double NextDouble(Random rng, double min, double max)
        {
            return min + (rng.NextDouble() * (max - min));
        }


    }
}
